package org.demo.base.auth.permission;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.demo.base.auth.domain.SysUser;
import org.demo.base.exception.NotLoginException;
import org.demo.base.exception.PermissionException;
import org.demo.base.util.LoginHelper;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

/**
 * 权限aop切面
 * @author tomdog
 */
@Component
@Aspect
@Slf4j// SpringBoot提供的日志打印
public class PermissionCheckAspect {

    /**
     * 拦截类上的注解
     */
    @Before("@within(p)")
    public void preCheckForClass(JoinPoint joinPoint, NeedPermission p) {
        log.debug("{} 拦截类上的注解：{}", 1, joinPoint.getSignature());
        permissionCheck(p.value());
    }

    /**
     * 拦截方法上的注解
     */
    @Before("@annotation(p)")
    public void preCheckForMethod(JoinPoint joinPoint, NeedPermission p) {
        permissionCheck(p.value());
    }

    /**
     * 验证权限
     * @param needPermissions 当前接口需要的权限
     *                        和当前用户拥有的权限进行对比
     */
    private void permissionCheck(String needPermissions) {
        // 如果注解里不需要权限，就不拦截
        if(needPermissions==null || needPermissions.isEmpty()) {
            return;
        }
        // 取出当前登录人的权限进行处理，这里一定能取到，因为是先进行登录拦截器，才会进行权限拦截
        // 除非你给一个无需登录的接口调用进行权限验证，这是没必要的，不登陆100%没有权限
        SysUser sysUser = LoginHelper.currentLoginUser();
        if(sysUser==null) {
            throw new NotLoginException();// 抛出未登录异常
        }
        // 如果已经登陆了才进行判断
        if(CollectionUtils.isEmpty(sysUser.getPermissions())) {
            throw new PermissionException(); // 用户拥有的权限为空
        }

        long count = sysUser.getPermissions().stream().filter(needPermissions::equals).count();
        if(count==0) {
            // 没有找到这个权限，抛出异常
            throw new PermissionException();
        }
    }
}
